﻿using System;
using System.IO;
using System.Security;
using System.Text;
using System.Windows.Forms;


namespace TextGenerator
{
    public partial class MainForm : Form
    {
        #region File Operations.
        /// <summary>
        /// Opens the specified file.
        /// </summary>
        /// <param name="filepath">The path and file name of the file to read the data from.</param>
        /// <returns>
        /// <see cref="String.Empty"/> if unable to open the file, 
        /// otherwise a string with the literal contents of the specified file.
        /// </returns>
        private static string OpenFile(string filepath)
        {
            if (String.IsNullOrEmpty(filepath))
                throw new ArgumentNullException();

            bool success = true;
            string errorMessage = String.Empty;
            string data = String.Empty;


            try
            {
                StreamReader sr = new StreamReader(filepath);
                data = sr.ReadToEnd();
                sr.Close();
            }
            catch (UnauthorizedAccessException)
            {
                // Access is denied.
                success = false;
                errorMessage = "Access is denied.";
            }
            catch (ArgumentNullException)
            {
                // Path is null. 
                success = false;
                errorMessage = String.Format("The path: {0}{1}{0} is invalid.", Environment.NewLine, filepath);
            }
            catch (ArgumentException)
            {
                // Path is empty. 
                success = false;
                errorMessage = String.Format("The path: {0}{1}{0} is invalid.", Environment.NewLine, filepath);
            }
            catch (FileNotFoundException)
            {
                // The file cannot be found. 
                success = false;
                errorMessage = String.Format("The file: {0}{1}{0} cannot be found.", Environment.NewLine, filepath);
            }
            catch (DirectoryNotFoundException)
            {
                // The specified path is invalid, such as being on an unmapped drive. 
                success = false;
                errorMessage = String.Format("The path: {0}{1}{0} is invalid. The directory is not found. Make sure it is not on an unmapped drive.", Environment.NewLine, filepath);
            }
            catch (PathTooLongException)
            {
                // The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 
                success = false;
                errorMessage = String.Format("The path: {0}{1}{0} is invalid. The path is too long. In Windows, paths must be less than 248 characters and file names must be less than 260 characters.", Environment.NewLine, filepath);
            }
            catch (IOException)
            {
                // Path includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.
                success = false;
                errorMessage = "I/O exception. Possibly incorrect syntax on file/directory name.";
            }
            catch (SecurityException)
            {
                // The caller does not have the required permission. 
                success = false;
                errorMessage = "Security exception. The user does not have the required permissions.";
            }
            catch (OutOfMemoryException)
            {
                // There is insufficient memory to allocate a buffer for the returned string. 
                success = false;
                errorMessage = "Insufficient memory to open the specified file.";
            }
            catch (Exception)
            {
                success = false;
                errorMessage = "Unknown error.";
            }


            // Inform the user if saving did not work.
            if (!success)
            {
                string message = String.Format("Unable to open file: {0}{1}", Environment.NewLine, errorMessage);
                MessageBox.Show(message, @"Error when opening", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }


            return data;
        }

        /// <summary>
        /// Saves the specified string to the specified file.
        /// </summary>
        /// <param name="filepath">The path and file name of the file to store the data in.</param>
        /// <param name="data">The literal data to store.</param>
        /// <returns>
        /// True if the save operation was successfull, 
        /// False otherwise.
        /// </returns>
        private static bool SaveFile(string filepath, string data)
        {
            if (String.IsNullOrEmpty(filepath))
                throw new ArgumentNullException();

            if (String.IsNullOrEmpty(data))
                throw new ArgumentNullException();

            bool success = true;
            string errorMessage = String.Empty;


            // Try and save the file.
            try
            {
                StreamWriter sw = new StreamWriter(filepath, false);
                sw.Write(data);
                sw.Flush();
                sw.Close();
            }
            catch (UnauthorizedAccessException)
            {
                // Access is denied.
                success = false;
                errorMessage = "Access is denied.";
            }
            catch (EncoderFallbackException)
            {
                // The current encoding does not support displaying half of a Unicode surrogate pair.
                success = false;
                errorMessage = "Encoding exception.";
            }
            catch (ArgumentException)
            {
                // Path is empty. 
                success = false;
                errorMessage = String.Format("The path: {0}{1}{0} is invalid.", Environment.NewLine, filepath);
            }
            catch (DirectoryNotFoundException)
            {
                // The specified path is invalid, such as being on an unmapped drive. 
                success = false;
                errorMessage = String.Format("The path: {0}{1}{0} is invalid. The directory is not found. Make sure it is not on an unmapped drive.", Environment.NewLine, filepath);
            }
            catch (PathTooLongException)
            {
                // The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 
                success = false;
                errorMessage = String.Format("The path: {0}{1}{0} is invalid. The path is too long. In Windows, paths must be less than 248 characters and file names must be less than 260 characters.", Environment.NewLine, filepath);
            }
            catch (IOException)
            {
                // Path includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.
                success = false;
                errorMessage = "I/O exception. Possibly incorrect syntax on file/directory name.";
            }
            catch (SecurityException)
            {
                // The caller does not have the required permission. 
                success = false;
                errorMessage = "Security exception. The user does not have the required permissions.";
            }
            catch (Exception)
            {
                success = false;
                errorMessage = "Unknown error.";
            }


            // Inform the user if saving did not work.
            if (!success)
            {
                string message = String.Format("Unable to save file: {0}{1}", Environment.NewLine, errorMessage);
                DialogResult dr = MessageBox.Show(message, @"Error when saving", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);

                // If the user presses Cancel, return true, indicating that 
                // this procedure went as the user wanted it to. 
                // If the user presses Retry, return false to indicate that 
                // the user is not happy with the result.
                success = (dr == DialogResult.Cancel);
            }


            return success;
        }
        #endregion File Operations.
    }
}